/*
 * Copyright 2015-2016 Amazon.com, Inc. or its affiliates.  All Rights Reserved.
 *
 * You may not use this file except in compliance with the terms and conditions set forth
 * in the accompanying LICENSE.TXT file.
 *
 * THESE MATERIALS ARE PROVIDED ON AN "AS IS" BASIS.  AMAZON SPECIFICALLY DISCLAIMS, WITH
 * RESPECT TO THESE MATERIALS, ALL WARRANTIES, EXPRESS, IMPLIED, OR STATUTORY, INCLUDING
 * THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, AND NON-INFRINGEMENT.
 */

package com.amazon.alexa.voicechrome;

import android.annotation.TargetApi;
import android.content.Context;
import android.os.Build;
import android.support.annotation.StringRes;
import android.util.AttributeSet;
import android.view.LayoutInflater;
import android.view.View;
import android.view.animation.AlphaAnimation;
import android.view.animation.Animation;
import android.widget.RelativeLayout;

import com.amazon.alexa.voicechrome.internal.views.ListeningView;
import com.amazon.alexa.voicechrome.internal.views.SpeakingView;
import com.amazon.alexa.voicechrome.internal.views.StaticView;
import com.amazon.alexa.voicechrome.internal.views.ThinkingView;
import com.amazon.alexa.voicechrome.internal.views.TransitionView;

/**
 * A View hosting Voice Chrome visuals.
 *
 * Abstracts the API contract for communicating with Voice Chrome visualization from the visual
 * implementations for clients of the Voice Chrome library.
 */
public class VoiceChromeVisuals extends RelativeLayout {
    public static final int BOTTOM_LAYER_START_DELAY = 200;
    public static final int BOTTOM_LATER_FADE_DURATION = 250;
    private ThinkingView thinkingView;
    private SpeakingView speakingView;
    private ListeningView listeningView;
    private StaticView staticView;
    private Animation fadeIn;
    private boolean isShowing;

    @VoiceChromeController.STATE
    private int currentState;
    public static boolean loggingEnabled;
    private CloseClickedCallback closeClickCallback;

    public VoiceChromeVisuals(Context context) {
        super(context);
        initView(context);
    }

    public VoiceChromeVisuals(Context context, AttributeSet attrSet) {
        super(context, attrSet);
        initView(context);
    }

    public VoiceChromeVisuals(Context context, AttributeSet attrSet, int defStyleAttr) {
        super(context, attrSet, defStyleAttr);
        initView(context);
    }

    @TargetApi(Build.VERSION_CODES.LOLLIPOP)
    public VoiceChromeVisuals(Context context, AttributeSet attrSet, int defStyleAttr, int defStyleRes) {
        super(context ,attrSet, defStyleAttr, defStyleRes);
        initView(context);
    }

    private void initView(final Context context) {
        LayoutInflater.from(context).inflate(R.layout.voicechrome_visuals, this);

        // Gather all the layouts for the states. StaticView is shared by all states that don't have interactions just color changes.
        listeningView = (ListeningView) findViewById(R.id.listening_view);
        thinkingView = (ThinkingView) findViewById(R.id.thinking_view);
        speakingView = (SpeakingView) findViewById(R.id.speaking_view);
        staticView = (StaticView) findViewById(R.id.static_view);

        fadeIn = new AlphaAnimation(0.0f, 1.0f);
        fadeIn.setDuration(250);

    }

    public void setThinking() {
        updateCurrentState(VoiceChromeController.THINK, thinkingView);
    }

    public void setSpeaking() {
        updateCurrentState(VoiceChromeController.SPEAK, speakingView);
}

    public void setListening() {

        updateCurrentState(VoiceChromeController.LISTEN, listeningView);
    }

    void setDoNotDisturb() {
        updateCurrentState(VoiceChromeController.DO_NOT_DISTURB, staticView);
        updateStaticState();
    }

    void setPrivacy() {
        updateCurrentState(VoiceChromeController.PRIVACY, staticView);
        updateStaticState();
    }

    void setUnavailable() {
        updateCurrentState(VoiceChromeController.UNAVAILABLE, staticView);
        updateStaticState();
    }

    void pause() {

    }

    void resume() {
        if (!isShowing) {

        }


        isShowing = true;
    }

    public void stop() {
        // If we're not currently visible, then don't change anything
        if (!isShowing) return;

        isShowing = false;
    }

    /**
     * Updates the current state with the provided state and associated view
     *
     * @param state
     * @param view
     */
    private void updateCurrentState(@VoiceChromeController.STATE int state, TransitionView view) {
//        No state change, so don't do anything
        if (currentState == state && view.isActive()) {
            return;
        }

        pause();

        currentState = state;


        resume();
    }

    /**
     * Updates the static UI elements for states
     */
    private void updateStaticState() {
        switch (currentState) {
            case (VoiceChromeController.SPEAK):
                staticView.setBarColor(R.color.voicechrome_bar_listening_color);
                staticView.setGradientDrawable(R.drawable.voicechrome_listening_gradient);
                break;
            case (VoiceChromeController.LISTEN):
                staticView.setBarColor(R.color.voicechrome_bar_listening_color);
                staticView.setGradientDrawable(R.drawable.voicechrome_listening_gradient);
                break;
            case (VoiceChromeController.THINK):
                staticView.setBarColor(R.color.voicechrome_bar_listening_color);
                staticView.setGradientDrawable(R.drawable.voicechrome_listening_gradient);
                break;
            case (VoiceChromeController.DO_NOT_DISTURB):
                staticView.setBarColor(R.color.voicechrome_bar_dnd_color);
                staticView.setGradientDrawable(R.drawable.voicechrome_dnd_gradient);
                break;
            case (VoiceChromeController.PRIVACY):
                staticView.setBarColor(R.color.voicechrome_bar_privacy_color);
                staticView.setGradientDrawable(R.drawable.voicechrome_privacy_gradient);
                break;
            case (VoiceChromeController.UNAVAILABLE):
                staticView.setBarColor(R.color.voicechrome_bar_unavailable_color);
                staticView.setGradientDrawable(R.drawable.voicechrome_unavailable_gradient);
                break;
            default:
                staticView.setBarColor(R.color.voicechrome_bar_listening_color);
                staticView.setGradientDrawable(R.drawable.voicechrome_listening_gradient);
                break;
        }
    }

    /**
     * gets the visibility of the close button for a given state
     *
     * @param currentState
     * @return int for View.Visibility (View.GONE, View.VISIBLE, View.INVISIBLE)
     */
    private int getCloseVisibility(@VoiceChromeController.STATE int currentState) {
        switch (currentState) {
            case (VoiceChromeController.SPEAK):
                return View.VISIBLE;
            case (VoiceChromeController.LISTEN):
            case (VoiceChromeController.THINK):
            case (VoiceChromeController.DO_NOT_DISTURB):
            case (VoiceChromeController.PRIVACY):
            case (VoiceChromeController.UNAVAILABLE):
            default:
                return GONE;
        }
    }

    /**
     * gets the string resource to be used in the state text
     *
     * @param currentState
     * @return int representing a string resource
     */
    private
    @StringRes
    int getStateText(@VoiceChromeController.STATE int currentState) {
        switch (currentState) {
            case (VoiceChromeController.SPEAK):
                return R.string.voicechrome_empty;
            case (VoiceChromeController.LISTEN):
                return R.string.voicechrome_listening_text;
            case (VoiceChromeController.THINK):
                return R.string.voicechrome_thinking_text;
            case (VoiceChromeController.DO_NOT_DISTURB):
                return R.string.voicechrome_do_not_disturb_text;
            case (VoiceChromeController.PRIVACY):
                return R.string.voicechrome_privacy_mode_text;
            case (VoiceChromeController.UNAVAILABLE):
                return R.string.voicechrome_unavailable_text;
            default:
                return R.string.voicechrome_empty;
        }
    }

    /**
     *  convenience method for editing listening view params
     * @return {@link ListeningView ListeningView}
     */
    public ListeningView getListeningView() {
        return listeningView;
    }

    public void setLoggingEnabled(boolean loggingEnabled) {
        VoiceChromeVisuals.loggingEnabled = loggingEnabled;
    }

    public void setUseBackgroundOverlayIntroAnimations(boolean useBackgroundOverlayAnimations) {

    }

    public void setCloseClickCallback(CloseClickedCallback closeClickCallback) {
        this.closeClickCallback = closeClickCallback;
    }

    /**
     * Callback for speaking state's close button
     */
    public interface CloseClickedCallback {
        void onCloseClick();
    }

    public void updateAnimation(float v){
        listeningView.updateAnimation(v);
    }

}
